﻿using System;
using System.Collections;
using System.Collections.Generic;
using UBlockly.Graphic;
using UnityEngine;
using UnityEngine.Experimental.PlayerLoop;

namespace UBlockly.Scriptable
{
    public sealed class NodeScriptable
    {
        private readonly ILFunc ilFunc;
        private ILVarType resultType;
        private uint varReturnCode;
        private readonly string[] paramsTypeStr;

        internal NodeScriptType ScriptType { get; }
        public string ResultTypeStr { get; }
        //参数个数，输入组件类型不算参数
        public uint ParamCount { get; }
        //复合节点
        public string[] TreeStrArray { get; }
        public ILVarType ResultType => resultType;
        public uint VarReturnCode => varReturnCode;
        
        public string VarParamTypeStr(uint paramIndex) => paramsTypeStr[paramIndex]; 
        public uint VarParamStr(uint paramIndex) => TranslateHelper.GetILVarTypeCodeByVarTypeName(paramsTypeStr[paramIndex]);

        private void Init()
        {
            resultType = TranslateHelper.GetILVarTypeByVarTypeName(ResultTypeStr);
            varReturnCode = TranslateHelper.GetILVarTypeCodeByVarTypeName(ResultTypeStr);
        }
        //常用函数
        public NodeScriptable(BlockDescribeData describeData)
        {
            ScriptType = NodeScriptType.NormalType;
            int count = describeData.ParamTypesStr == null ? 0 : describeData.ParamTypesStr.Length;
            ilFunc = new BlockILFunc(describeData.FunctionName);
            
            ResultTypeStr = describeData.ResultTypeStr;
            if (describeData.ParamTypesStr != null && count != 0)
            {
                paramsTypeStr = new string[count];
                describeData.ParamTypesStr.CopyTo(paramsTypeStr, 0);
            }
            ParamCount = (uint)count;
            Init();
        }
        //复合函数
        public NodeScriptable(string[] treeStrArray, params string[] paramsStr)
        {
            TreeStrArray = new string[treeStrArray.Length];
            treeStrArray.CopyTo(TreeStrArray,0);
            ScriptType = NodeScriptType.ComplexType;
            ilFunc = new ComplexBlockILFunc(treeStrArray);
            ResultTypeStr = SerializeTreeNode.FromStr(treeStrArray[0]).ReturnTypeStr;
            var count = paramsStr == null ? 0 : paramsStr.Length;
            if (count > 0)
            {
                paramsTypeStr = new string[count];
                paramsStr.CopyTo(paramsTypeStr, 0);
            }

            ParamCount = (uint) count;
            Init();
        }
        //默认函数
        public NodeScriptable(DefaultParamIlFunc func,string resultStr)
        {
            ScriptType = NodeScriptType.DefaultType;
            ilFunc = func;
            ResultTypeStr = resultStr;
            ParamCount = 0;
            Init();
        }

        public ILFunc GetFunc()
        {
            return ilFunc;
        }
        //只有default
        internal IVarObject GetDefaultValue()
        {
            if (ilFunc is DefaultParamIlFunc)
            {
                return ((DefaultParamIlFunc)ilFunc).GetDefaultValue();
            }

            throw new SystemException("only DefaultParamNode can GetDefaultValue");
        }
    }
}